package cn.nhs.schedule.task;

import cn.nhs.schedule.common.Constants;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**

 */
@Component("nhs-schedule-cronTaskRegister")
public class CronTaskRegister implements DisposableBean {

    // 这里本质上是定义了一个 ThreadPoolTaskScheduler 的线程池
    @Resource(name = "nhs-schedule-taskScheduler")
    private TaskScheduler taskScheduler;

    public TaskScheduler getScheduler() {
        return this.taskScheduler;
    }

    // 添加任务 & 启动任务
    public void addCronTask(SchedulingRunnable task, String cronExpression) {
        // 首先判断是否已经存在这个任务了，如果存在，那么先移除这个任务
        if (null != Constants.scheduledTasks.get(task.taskId())) {
            removeCronTask(task.taskId());
        }
        // 然后再启动
        CronTask cronTask = new CronTask(task, cronExpression);
        Constants.scheduledTasks.put(task.taskId(), scheduleCronTask(cronTask));
    }

    private ScheduledTask scheduleCronTask(CronTask cronTask) {
        ScheduledTask scheduledTask = new ScheduledTask();
        // 线程池去执行任务，然后使用 scheduledTask.future 同步接收
        scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
        return scheduledTask;
    }

    // 移除任务
    public void removeCronTask(String taskId) {
        ScheduledTask scheduledTask = Constants.scheduledTasks.remove(taskId);
        if (scheduledTask == null) return;
        // 其内部调用 ScheduledFuture 的 cancel 方法
        scheduledTask.cancel();
    }


    @Override
    public void destroy() {
        for (ScheduledTask task : Constants.scheduledTasks.values()) {
            task.cancel();
        }
        Constants.scheduledTasks.clear();
    }

}

